home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of MacTutor - S…e Code for Volumes 1 to 5
/
The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin
/
Source Code
/
#03 (Aug85-Sep85)
/
Basic
/
Prof. Mac Vol. 1 #10
/
basic sort program
(
.txt
)
Wrap
AmigaBASIC Source Code
|
1985-07-22
|
4KB
|
139 lines
REM Set up test data for Sort routine; do a timed call
REM and verify that routine worked.
DIM Test$(599) ' 600 strings
TotLen = 0
FOR I% = 0 TO 599
Test$(I%) = STR$(RND)
TotLen = TotLen + LEN(Test$(I%))
NEXT
PRINT USING "Average length of the 600 strings is ##.#";TotLen/600
PRINT "Sorting..."
Start = TIMER
CALL Sort(Test$())
PRINT "Sort took";TIMER-Start;"seconds; checking correctness..."
FOR I% = 0 TO 598
IF Test$(I%) > Test$(I%+1) THEN PRINT "Oops, didn't work!" : END
NEXT
PRINT "It worked!"
END
REM ---------------Sort Subprogram follows---------------------
REM
SUB Sort(S$(1)) STATIC
REM
REM Optimized Quicksort subprogram to sort
REM an array of strings into ascending order.
REM Algorithm adapted from:
REM Sedgewick, Communications of the ACM, V21 N10, Oct. 1978
REM and corrigendum, V22 N6, Jun. 1979
REM Also see Chapter 9 of Sedgewick, "Algorithms",
REM Addison-Wesley, 1983, ISBN 0-201-6672-6
REM
REM Rather than use recursion, use a stack of array partitions --
REM The "Dimmed" kludge seems to be required to get a truly local array
REM in a SUB that may be called more than once:
IF NOT Dimmed THEN DIM Stack%(15,2) ' 15 handles 32,768 elements
Dimmed = 1
REM
REM Sedgewick's "M" parameter, which determines when to stop Quicksorting AND
REM finish up with an insertion sort on entire array (an optimization):
Insertion% = 10
REM
L% = LBOUND(S$) ' "left" subscript
R% = UBOUND(S$) ' "right" subscript
IF L% = R% THEN EXIT SUB ' One element is easy to sort!
IF R% - L% < Insertion% THEN GOTO InsertionSort
StackPtr% = 0
REM Initialize for partitioning the subarray such that the partitioning
REM element S$(L%) is the median of: old S$(L%), S$(Middle%), S$(R%)
PartInit:
Middle% = (L%+R%) / 2
REM Lines beginning with "Temp$ =" are exchanges of array elements
Temp$ = S$(Middle%) : S$(Middle%) = S$(L%) : S$(L%) = Temp$
IF S$(L%+1) <= S$(R%) THEN GOTO P2
Temp$ = S$(L%+1) : S$(L%+1) = S$(R%) : S$(R%) = Temp$
P2:
IF S$(L%) <= S$(R%) THEN GOTO P3
Temp$ = S$(L%) : S$(L%) = S$(R%) : S$(R%) = Temp$
P3:
IF S$(L%+1) <= S$(L%) THEN GOTO Partition
Temp$ = S$(L%+1) : S$(L%+1) = S$(L%) : S$(L%) = Temp$
Partition:
I% = L%+1
J% = R%
Partitioner$ = S$(L%)
IncI:
I% = I% + 1
IF Partitioner$ >= S$(I%) THEN GOTO IncI
DecJ:
J% = J% - 1
IF S$(J%) > Partitioner$ THEN GOTO DecJ
IF I% >= J% THEN GOTO GotIJ
Temp$ = S$(I%) : S$(I%) = S$(J%) : S$(J%) = Temp$
GOTO IncI
GotIJ:
S$(L%) = S$(J%)
S$(J%) = Partitioner$
REM Determine what to do next depending on relative and absolute
REM sizes of subarrays
NL% = J% - L% ' size of left subarray
NRM1% = R% - I% ' (size of right subarray) - 1
IF NL% > NRM1% THEN GOTO BigLeft
REM Right subarray is larger
IF NRM1% < Insertion% THEN GOTO CheckStack
IF NL% > Insertion% THEN GOTO LeftNext
REM Partition right subarray next
L% = I%
GOTO PartInit
REM Left subarray is larger (or equal)
BigLeft:
IF NL% <= Insertion% THEN GOTO CheckStack
IF NRM1% >= Insertion% THEN GOTO RightNext
R% = J% - 1
GOTO PartInit
REM "Push" right subarray, partition left subarray next
LeftNext:
StackPtr% = StackPtr% + 1
Stack%(StackPtr%,1) = I%
Stack%(StackPtr%,2) = R%
R% = J% - 1
GOTO PartInit
REM "Push" left subarray, partition right subarray next
RightNext:
StackPtr% = StackPtr% + 1
Stack%(StackPtr%,1) = L%
Stack%(StackPtr%,2) = J% - 1
L% = I%
GOTO PartInit
REM If stack not empty, pop and partition; else finish with insertion sort
CheckStack:
IF StackPtr% = 0 GOTO InsertionSort
REM Pop subarray specifier stack into L%, R%
L% = Stack%(StackPtr%, 1)
R% = Stack%(StackPtr%, 2)
StackPtr% = StackPtr% - 1
GOTO PartInit
REM
REM Insertion sort on entire array
REM
InsertionSort:
FOR I% = UBOUND(S$)-1 TO LBOUND(S$) STEP -1
IF S$(I%+1) > S$(I%) THEN GOTO Loop
Work$ = S$(I%)
J% = I% + 1
Slide: S$(J%-1) = S$(J%)
J% = J% + 1
IF J% <= UBOUND(S$) THEN IF Work$ >= S$(J%) THEN GOTO Slide
S$(J%-1) = Work$
Loop: NEXT
END SUB
REM------------End of Sort subprogram------------------------